package com.zys.el.user.controller;

import com.alibaba.fastjson.JSONObject;
import com.zys.el.core.po.ResponseBean;
import com.zys.el.user.config.po.DoubleTarget;
import com.zys.el.user.config.po.Make;
import com.zys.el.user.config.po.Start;
import com.zys.el.user.po.*;
import com.zys.el.user.service.*;
import com.zys.el.user.util.FPGrowth.Myfptree2;
import com.zys.el.user.util.TunxunApi.DiretSimilar;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;

import java.util.*;
import java.util.stream.Collectors;

@CrossOrigin
@RestController
@RequestMapping(value = "/make-target")
public class StartController {
    @Autowired
    private ITargetService targetService;
    @Autowired
    private ITargetUserService targetUserService;
    @Autowired
    private ITaskService taskService;
    @Autowired
    private IUserService userService;
    @Autowired
    private IProssionService prossionService;
    @Autowired
    private Myfptree2 fp;

    /**
     * 通过用户id得到该用户的目标和任务列表
     *
     * @param userId
     * @return
     */
    @GetMapping("/stater/{id}")
    public ResponseBean getStaterByUserId(@PathVariable("id") Long userId) {
        ResponseBean rn = new ResponseBean();

        TargetUser targetUser = targetUserService.selectTargetByUserId(userId);
        Target target = targetService.getById(targetUser.getTargetId());

        List<Task> tasks = taskService.getTaskByTargetId(target.getId());
        List<String> collect = tasks.stream().map(Task::getName).collect(Collectors.toList());
        Start start = Start.builder().targetName(target.getName()).tasks(collect).build();
//        System.out.println(start);
        rn.setModel(start);
        return rn;
    }

    /**
     * 得到通用目标列表、同专业会选的目标列表、已选目标
     *
     * @return
     */
    @GetMapping("/target-list/{userId}")
    public ResponseBean getTargetList(@PathVariable Long userId) {
        ResponseBean rn = new ResponseBean();

        Map<String, Long> professionTarget = new HashMap<>();//专业目标
        Map<String, Long> commentTarget = new HashMap<>(); //通用目标
        Map<String, Long> ReadyTarget = new HashMap<>(); // 已完成的目标
        User user = userService.getById(userId);
        if (user == null) {
            rn.setSuccess(false);
            rn.setCode(500);
            rn.setMsg("获取用户信息失败，请检查用户是否不存在");
            return rn;
        } else {
            if (user.getProfessionId() == null) {
                rn.setSuccess(false);
                rn.setCode(500);
                rn.setMsg("用户还未填写个人专业信息，获取专业信息失败");
                return rn;
            } else {
                Prossion profession = prossionService.getById(user.getProfessionId());//得到用户专业信息
                //得到所有用户
                List<User> users = userService.list();
                if (users == null || users.size() == 0) {
                    rn.setSuccess(false);
                    rn.setCode(500);
                    rn.setMsg("服务器错误");
                    return rn;
                }

                List<Target> targets = targetService.list();
                for (Target target : targets) {
                    TargetUser targetUser = targetUserService.selectTargetByTargetId(target.getId());
                    if (targetUser == null) continue;
                    User u = userService.getById(targetUser.getUserId());
                    if (u == null) continue;
                    Prossion prossionServiceById = prossionService.getById(u.getProfessionId());
                    if (prossionServiceById == null) continue;
                    if (target.getType() == 1) {
                        // TODO 已修改
                        ////////////////////////////////////修改未提交///////////////////////////////////////////
                        DiretSimilar ds = new DiretSimilar();
//                        System.out.println(prossionServiceById.getProssionName()+ profession.getProssionName());
                        String s1 = prossionServiceById.getProssionName().length() >= 4 ?
                                prossionServiceById.getProssionName().substring(0,4) : prossionServiceById.getProssionName();
                        String s2 = profession.getProssionName().length() >= 4 ? profession.getProssionName().substring(0, 4) : profession.getProssionName();
                        String result = ds.result(s1, s2);
                        String similarity = JSONObject.parseObject(result).get("Similarity").toString();
                        if (Double.parseDouble(similarity) >= 0.4) {//判断用户是否同专业 -》采用词义分析
                       ////////////////////////////////////////////////////////////////////////
                            if (professionTarget.get(target.getName()) == null) {
                                professionTarget.put(target.getName(), 1L);
                            } else {
                                professionTarget.put(target.getName(),
                                        professionTarget.get(target.getName()) + 1);
                            }

                        }

                    } else if (target.getType() == 0) {
                        if (commentTarget.get(commentTarget.get(target.getName())) == null) {
                            commentTarget.put(target.getName(), 1L);
                        } else {
                            commentTarget.put(target.getName(), commentTarget.get(target.getName()) + 1);
                        }
                        //得到通用目标和对应的值
                    } else {
                        continue;
                    }
                }
            }
        }
//        //从大到小排序
//        class MyComparator implements Comparator<Map.Entry> {
//            public int compare(Map.Entry o1, Map.Entry o2) {
//                return ((Long) o2.getValue()).compareTo((Long) o1.getValue());
//            }
//        }
//        List<Map.Entry<String, Long>> entryList = new ArrayList<>(professionTarget.entrySet());
//        Collections.sort(entryList, new MyComparator());
//
//        System.out.println("professionTarget : " + professionTarget);
//        System.out.println("commentTarget : " + commentTarget);
        // 去除已通过目标
        //得到用户已完成的目标
        List<TargetUser> menu = targetUserService.query().eq("user_id_", userId).list();
        for (TargetUser targetUser : menu) {
            Target target = targetService.getById(targetUser.getTargetId());
            if (target == null) continue;
            if (target.getFanish() == 1) {
                professionTarget.remove(target.getName());
                commentTarget.remove(target.getName());
                if (ReadyTarget.get(target.getName()) == null) {
                    ReadyTarget.put(target.getName(), 1L);
                } else {
                    ReadyTarget.put(target.getName(), ReadyTarget.get(target.getName()) + 1);
                }
            }
        }
//        System.out.println("ReadyTarget: " + ReadyTarget);

        DoubleTarget build = DoubleTarget.builder().professionTarget(professionTarget).commentTarget(commentTarget).ReadyTarget(ReadyTarget).build();
        rn.setModel(build);
        return rn;

    }


    /**
     * 根据选择的目标名称得到任务列表
     *
     * @param name
     * @return 返回含有六个列表的数据的，其中前五个为五个最赞任务组。第六个为散列推荐任务组
     */
    @GetMapping("/recommon/{target}")
    public ResponseBean getRecommonTask(@PathVariable("target") String name) {

        ResponseBean rn = new ResponseBean();
        ////////////////////////////获取五个最赞组合////////////////////////////////////////
        List<Target> targets = targetService.selectListByNameToOrderByLike(name);
        Set<List<String>> result = new HashSet<>();
        int temp = 5;
        if (targets.size() < 5) {
            for (int i = 0; i < targets.size(); i++) {

                List<String> tasks = new ArrayList<>(
                        new HashSet<>(taskService.getTaskByTargetId(targets.get(i).getId())
                                .stream().map(Task::getName).collect(Collectors.toList())));

                if (tasks.size() == 0) continue;
                result.add(tasks);
            }
        } else {
            for (int i = 0; i < temp; i++) {
                List<String> tasks = new ArrayList<>(
                        new HashSet<>(taskService.getTaskByTargetId(targets.get(i).getId())
                                .stream().map(Task::getName).collect(Collectors.toList())));
                if (tasks.size() == 0 && targets.size() > temp) {
                    temp++;
                    continue;
                }
                result.add(tasks);
            }
        }
//        System.out.println("result: " + result);
        /////////////////////////////////散列表//////////////////////////////
        //根据target名字查出所有的target目标id列表
       /*
        List<Target> targetByName = targets;
        Set<String> strings = null;
        if (targetByName.equals(null) == false) {
            //根据目标id列表一个个查出所有的对应的任务分解存到一个List<List<String>>中
            List<List<String>> fpList = new ArrayList<>();
            for (int i = 0; i < targetByName.size(); i++) {
                List<Task> taskByTargetId = taskService.getTaskByTargetId(targetByName.get(i).getId());
                if (taskByTargetId.equals(null) == false) {
                    fpList.add(new ArrayList<>());
                    for (Task task : taskByTargetId) {
                        fpList.get(i).add(task.getName());
                    }
                }
            }
//            System.out.println("fpList" + fpList);
            if (fpList.size() == 0) {
                rn.setModel(strings);
                return rn;
            }
            //采用算法得到一个推荐任务列表
            List<String> ownT = new ArrayList<>();

            strings = fp.FPTreeLL(fpList, ownT);
        }
//        System.out.println("result: " + result);

        */
        List<List<String>> resultFive = new ArrayList<>(result);
//        List<String> resultStrings = new ArrayList<>(strings);
//        resultFive.add(resultStrings);

        rn.setModel(resultFive);
        return rn;

    }

    /**
     * 保存目标
     *
     * @param make
     * @return
     */
    @ApiOperation(value = "保存", notes = "ID存在修改，不存在添加")
    @Transactional(propagation = Propagation.REQUIRED)
    @PostMapping("/save-taget")
    public ResponseBean save(@RequestBody Make make) {
        ResponseBean rn = new ResponseBean();

        if (make.getUserId() == null) {
            rn.setSuccess(false);
            rn.setMsg("服务器异常，缺少用户id，请重新尝试");
            rn.setCode(500);
            return rn;
        }
        if (make.getType() == null || (make.getType() != 0 && make.getType() != 1 && make.getType() != 2)) {
            rn.setSuccess(false);
            rn.setMsg("服务器异常，目标类型错误，请重新尝试，只能是0 1 2");
            rn.setCode(500);
            return rn;
        }
        if (make.getTarget() == null || make.getTarget().equals("")) {
            rn.setSuccess(false);
            rn.setMsg("服务器异常，目标未设置，请重新尝试");
            rn.setCode(500);
            return rn;
        }
        if (make.getTasks().size() < 2 || make.getTasks() == null) {
            rn.setSuccess(false);
            rn.setMsg("服务器异常，至少要有两个合理任务，请重新尝试");
            rn.setCode(500);
            return rn;
        }

        //插入目标
        Target target = new Target();
        target.setName(make.getTarget());
        target.setType(make.getType());
        target.setUserId(make.getUserId());
        target.setDelete(0);
//        System.out.println(target);
        Long targetId = targetService.SaveOrUpdateTarget(target, target.getUserId());
        if (targetId == 0) {
            rn.setMsg("服务器异常");
            rn.setCode(500);
        }
        //插入任务
        // 根据目标id查询任务表，如果能查到就删掉 然后再插入
        // 如果为空就直接插入
        List<Task> taskByTargetId = taskService.getTaskByTargetId(targetId);
        if (taskByTargetId == null || taskByTargetId.size() == 0) { // 该目标还未有任务就直接插入
            for (Task task : make.getTasks()) {
                if (task.getName() == null || task.getTimeLength() == null || task.getTimeLength() == "") {
                    rn.setMsg("服务器异常，任务名称或任务时长未设置，请重新尝试");
                    rn.setCode(500);
                    return rn;
                }
            }
            for (Task task : make.getTasks()) {
                Task taskNew = new Task();
                taskNew.setDelete(0);
                taskNew.setName(task.getName());
                taskNew.setTimeLength(task.getTimeLength());
                taskNew.setTargetId(targetId);
                taskNew.setCreateTime(new Date());
                boolean save = taskService.save(taskNew);
                if (save == false) {
                    rn.setSuccess(false);
                    rn.setCode(400);
                    rn.setToken("服务器异常");
                }
            }
        } else { //有任务就删除再插入
            for (Task task : make.getTasks()) {
                if (task.getName() == null || task.getTimeLength() == null || task.getTimeLength() == "") {
                    rn.setSuccess(false);
                    rn.setMsg("服务器异常，任务名称或任务时长未设置，请重新尝试");
                    rn.setCode(500);
                    return rn;
                }
            }
            //删除该目标的所有任务
            for (Task task : taskByTargetId) {
                task.setDelete(1);
                taskService.saveOrUpdate(task);
            }

            //插入任务组
            for (Task task : make.getTasks()) {
                Task taskNew = new Task();
                taskNew.setDelete(0);
                taskNew.setName(task.getName());
                taskNew.setTimeLength(task.getTimeLength());
                taskNew.setTargetId(targetId);
                taskNew.setCreateTime(new Date());
                boolean save = taskService.save(taskNew);
                if (save == false) {
                    rn.setSuccess(false);
                    rn.setMsg("服务器异常");
                    rn.setCode(400);
                }
            }
        }
        return rn;

    }


}
